﻿using System;
using System.Windows;
using System.Windows.Input;
using Utils.Wpf;

namespace StockAnalyst2.Options
{
	internal class OptionsVM : ViewModelBase
	{
		#region Attributes

		private readonly ApplicationOptions _originalOptions;

		#endregion

		#region Properties

		public ApplicationOptionsVM ApplicationOptionsVM { get; private set; }

		public bool DataChanged
		{
			get
			{
				return !_originalOptions.Equals(this.ApplicationOptionsVM.Model);
			}
		}

		public ICommand AcceptCommand { get; private set; }
		public ICommand CancelCommand { get; private set; }

		#endregion

		#region Events

		public event EventHandler<DialogCloseRequestedEventArgs> DialogCloseRequested;
		public event EventHandler<MessageBoxRequestedEventArgs> MessageBoxRequested; 
		#endregion

		#region Public Methods

		public OptionsVM(ApplicationOptions applicationOptions)
		{
			_originalOptions = applicationOptions;
			this.ApplicationOptionsVM = new ApplicationOptionsVM((ApplicationOptions)_originalOptions.Clone());

			this.AcceptCommand = new DelegateCommand(this.ExecuteAccept, this.CanExecuteAccept);
			this.CancelCommand = new DelegateCommand(this.ExecuteCancel);
		}

		protected virtual void OnDialogCloseRequested(bool? result)
		{
			if (this.DialogCloseRequested != null)
			{
				this.DialogCloseRequested(this, new DialogCloseRequestedEventArgs(result));
			}
		}

		protected virtual void OnMessageBoxRequested(string caption, string message, MessageBoxImage icon)
		{
			if (this.MessageBoxRequested != null)
			{
				this.MessageBoxRequested(this, new MessageBoxRequestedEventArgs(caption, message, icon));
			}
		}

		#endregion

		#region Private Methods

		private void ExecuteAccept()
		{
			if (this.AreValuesValid())
			{
				this.OnDialogCloseRequested(true);

				ApplicationOptionsDataSource.Save(this.ApplicationOptionsVM.Model);
			}
		}

		private bool CanExecuteAccept()
		{
			return !this.ApplicationOptionsVM.HasValidationErrors;
		}

		private void ExecuteCancel()
		{
			this.OnDialogCloseRequested(false);
		}

		private bool AreValuesValid()
		{
			bool result;

			DataBaseChecker checker = new DataBaseChecker(this.ApplicationOptionsVM.Model.DatabaseServer, this.ApplicationOptionsVM.Model.DatabaseName);
			
			if (!checker.IsDataBaseServerAvailable())
			{
				this.OnMessageBoxRequested("Invalid server", string.Format("Cannot find the server {0}",this.ApplicationOptionsVM.Model.DatabaseServer) , MessageBoxImage.Error);
				result = false;
			}
			else if (!checker.IsDataBaseAvailable())
			{
				this.OnMessageBoxRequested("Invalid database", string.Format("Cannot find the database {0} on the server {1}", this.ApplicationOptionsVM.Model.DatabaseName, this.ApplicationOptionsVM.Model.DatabaseServer), MessageBoxImage.Error);
				result = false;
			}
			else if (!checker.IsDataBaseStructureValid())
			{
				this.OnMessageBoxRequested("Invalid db structure", string.Format("The database {0} on the server {1} does not contain the required structure / tables", this.ApplicationOptionsVM.Model.DatabaseName, this.ApplicationOptionsVM.Model.DatabaseServer), MessageBoxImage.Error);
				result = false;
			}
			else
			{
				result = true;
			}

			return result;
		}

		#endregion

	}
}
